package com.cq.hd.order.processor.settle;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.cq.hd.common.enums.biz.BillTypeEnum;
import com.cq.hd.common.enums.biz.MemberAmtBillTradeTypeEnum;
import com.cq.hd.common.enums.biz.MonthSettleStateEnum;
import com.cq.hd.common.enums.biz.OrderSettleBillTradeTypeEnum;
import com.cq.hd.common.utils.NoUtils;
import com.cq.hd.member.api.dto.MerchantAmtAddDto;
import com.cq.hd.member.api.dto.MerchantAmtBillSaveDto;
import com.cq.hd.member.api.vo.MerchantVo;
import com.cq.hd.order.api.dto.MonthSettleGroupKeyDto;
import com.cq.hd.order.api.dto.OrderSettleBillDto;
import com.cq.hd.order.api.vo.OrderSettleBillVo;
import com.cq.hd.order.po.TbMonthSettleBillPo;
import com.cq.hd.order.po.TbOrderSettleBillItemPo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 月度结算 - 商户补贴处理器
 *
 * @author much
 * @since 2024/04/14 20:45
 */
@Slf4j
@Component
public class MerchantSubsidyMonthSettleProcessor extends AbstractMonthSettleProcessor {

    @Override
    protected List<OrderSettleBillVo> queryWaitProcessBills() {
        OrderSettleBillDto param = new OrderSettleBillDto();
        param.setTradeType(OrderSettleBillTradeTypeEnum.SUBSIDY_AMT.getValue());
        param.setMonthSettleState(MonthSettleStateEnum.WAIT.getValue());
        // 查询最近3个月的记录
        Date now = DateUtil.date();
        DateTime startDate = DateUtil.beginOfMonth(DateUtil.offsetMonth(now, -3));
        param.setStartTradeTime(DateUtil.format(startDate, "yyyy-MM-dd"));
        param.setEndTradeTime(DateUtil.format(DateUtil.beginOfMonth(now), "yyyy-MM-dd"));
        return orderSettleBillService.listByDto(param);
    }

    @Override
    protected TbMonthSettleBillPo getMonthSettleBill(MonthSettleGroupKeyDto groupKeyDto, List<OrderSettleBillVo> dataList) {
        TbMonthSettleBillPo tbMonthSettleBillPo = newMonthSettleBill(groupKeyDto, dataList, 2);
        // save monthSettleBill
        monthSettleBillMapper.insert(tbMonthSettleBillPo);
        return tbMonthSettleBillPo;
    }

    @Override
    protected MerchantAmtAddDto calculateMerchantAmtAddDto(Long merchantId, List<TbOrderSettleBillItemPo> orderSettleBillItems) {
        MerchantAmtAddDto merchantAmtAddDto = new MerchantAmtAddDto();
        merchantAmtAddDto.setId(merchantId);
        BigDecimal totalAmt = orderSettleBillItems.stream()
                .map(TbOrderSettleBillItemPo::getTradeAmt)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        merchantAmtAddDto.setSubsidyAmt(totalAmt);
        merchantAmtAddDto.setBalanceAmt(BigDecimal.ZERO);
        return merchantAmtAddDto;
    }

    @Override
    protected List<MerchantAmtBillSaveDto> generateMerchantAmtBills(MerchantVo merchantVo, List<TbOrderSettleBillItemPo> orderSettleBillItems) {
        List<MerchantAmtBillSaveDto> merchantAmtBillSaveList = new ArrayList<>(orderSettleBillItems.size());
        LocalDateTime now = LocalDateTime.now();
        for (TbOrderSettleBillItemPo item : orderSettleBillItems) {
            MerchantAmtBillSaveDto merchantAmtBillSaveDto = BeanUtil.copyProperties(item, MerchantAmtBillSaveDto.class);
            merchantAmtBillSaveDto.setBillNo(NoUtils.getMemberAmtBillNo());
            merchantAmtBillSaveDto.setBillType(BillTypeEnum.INCOME.getValue());
            merchantAmtBillSaveDto.setTradeType(MemberAmtBillTradeTypeEnum.ORDER_SUBSIDY.getValue());
            merchantAmtBillSaveDto.setRelationTradeNo(item.getSubOrderNo());
            merchantAmtBillSaveDto.setTradeTime(now);
            merchantAmtBillSaveDto.setCreateTime(now);
            merchantAmtBillSaveDto.setUpdateTime(now);
            merchantAmtBillSaveDto.setBeforeAmt(merchantVo.getSubsidyAmt());
            merchantAmtBillSaveDto.setTradeAmt(item.getTradeAmt());
            merchantAmtBillSaveDto.setAfterAmt(merchantAmtBillSaveDto.getBeforeAmt().add(item.getTradeAmt()));
            merchantAmtBillSaveList.add(merchantAmtBillSaveDto);
            // 更新一下商户余额
            merchantVo.setSubsidyAmt(merchantAmtBillSaveDto.getAfterAmt());
        }
        return merchantAmtBillSaveList;
    }

}
